package com.ashin.plugin;

import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;

import java.lang.reflect.Field;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Properties;

/**
 * @Author: Ashin
 * @Date: 2020/9/2
 * @Description: com.juggernaut.plugin
 * @Version: 1.0.0
 */
@Intercepts({
        @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class ResultSetInterceptor implements Interceptor {


    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object result = invocation.proceed();
        if (Objects.isNull(result)) {
            return null;
        }

        if (result instanceof ArrayList) {
            ArrayList resultList = (ArrayList) result;
            if (!resultList.isEmpty() && needToDecrypt(resultList.get(0))) {

                Field[] declaredField = resultList.get(0).getClass().getDeclaredFields();
                List<Field> needDecryptField = new ArrayList<>(declaredField.length);
                for (Field field : declaredField) {
                    if (field.isAnnotationPresent(EncryptDecrypt.class)) {
                        needDecryptField.add(field);
                    }
                }

                for (Object aResult : resultList) {
                    for (Field field : needDecryptField) {
                        field.setAccessible(true);
                        field.set(aResult, "解密");
                        field.setAccessible(false);
                    }
                }
            }

        } else {
            System.out.print("非arraylist 对象");
        }
        return result;
    }

    public boolean needToDecrypt(Object object) {
        Class<?> objectClass = object.getClass();
        Field[] declaredFields = objectClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            boolean annotationPresent = declaredField.isAnnotationPresent(EncryptDecrypt.class);
            if (annotationPresent) {
                return true;
            }
        }

        return false;
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}